package com.fxu.framework.core.exception;

import com.fxu.framework.core.base.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import java.util.Objects;

/**
 * Restfull 异常统一处理
 * 默认错误屏蔽[注释调了@ControllerAdvice]
 * @author fangxu
 * @version 1.0.0
 */
@Slf4j
//@ControllerAdvice(annotations = RestController.class)
public class ErrorHandler {

	@ResponseBody
	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseStatus(HttpStatus.OK)
	public Result<String> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
		String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\.");
		String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
		if ("不能为空".equals(message)) {
			message = str[1] + ":" + message;
		}
		// FieldError fieldError = e.getBindingResult().getFieldError();
		log.error("MethodArgumentNotValidException!e={}", e.getMessage(), e);
		return Result.error(message);
	}

	@ResponseBody
	@ExceptionHandler(HttpMessageNotReadableException.class)
	@ResponseStatus(HttpStatus.OK)
	public Result<String> httpMessageNotReadableException(HttpMessageNotReadableException e) {
		log.error("HttpMessageNotReadableException!msg={}", e.getMessage(), e);
		return Result.error("Request params is incorrect!");
	}

	@ResponseBody
	@ExceptionHandler(MsgException.class)
	@ResponseStatus(HttpStatus.OK)
	public Result<String> msgExceptionHandler(MsgException e, HttpServletResponse resp) {
		resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
		if (e.getRestStatus() == null) {
			log.error("MsgException!msg=" + e.getMessage(), e);
		} else {
			log.error("MsgException!code=" + e.getRestStatus().code() + ",msg=" + e.getRestStatus().desc(), e);
		}
		return Result.error(e.getRestStatus() == null ? e.getMessage() : e.getRestStatus().toString());
	}

	@ResponseBody
	@ExceptionHandler
	@ResponseStatus(HttpStatus.OK)
	public Result<String> runtimeExceptionHandler(Exception e, HttpServletResponse resp) {
		resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
		if (e.getClass() == ClientAbortException.class && e.getMessage().equals("java.io.IOException: Connection reset by peer")) {
			log.error("java.io.IOException: Connection reset by peer");
		} else {
			log.error("Exception!", e);
		}
		return Result.error("Service running error!e=" + e.getMessage());
	}

	// 参数校验异常拦截
	@ResponseBody
	@ExceptionHandler(ConstraintViolationException.class)
	@ResponseStatus(HttpStatus.OK)
	public Result<String> handleConstraintViolationException(ConstraintViolationException e) {
		return Result.error(e.getMessage());
	}
}